Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Fix compilation issues with MSVC 2017 #196

Merged
merged 12 commits into from
Jul 26, 2023
Merged

Conversation

miscco
Copy link
Collaborator

@miscco miscco commented Jul 11, 2023

Currently we have issues in CI when building with MSVC 2017

This PR fixes that and enables us to pass CI cleanly even with MSVC 2017 and up

It also introduces some minor cleanups

Fixes #173

@miscco miscco added libcu++ For all items related to libcu++ bug Something isn't working right. labels Jul 11, 2023
@miscco miscco requested review from griwes and wmaxey July 11, 2023 15:26
@miscco miscco self-assigned this Jul 11, 2023
@miscco miscco changed the title Fix compilation issues with MSVC 2017 [BUG] Fix compilation issues with MSVC 2017 Jul 11, 2023
Copy link
Collaborator

@griwes griwes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One overarching thing I noticed with these changes is how inconsistent we are with the placement of constexpr, and how you're doing a bunch of changes in one of the files, but not in the other ones. We need to have a style guide conversation at some point, but since we're already heavily inconsistent, it'd be nice to avoid the noise of changing this in just some of the places, and in a change set that's not related to formatting.

(Ideally we'd just figure out a common clang format config for everything and reformat everything in one go, I guess? I think there's a way to mark commits as irrelevant in git blame, so just doing this in a single, specialized commit would be ideal.)

@@ -39,7 +42,9 @@ void testRuntimeSpan(Span sp)
assert(spBytes.extent == sizeof(typename Span::element_type) * sp.extent);

assert((void *) spBytes.data() == (void *) sp.data());
#ifndef TEST_COMPILER_MSVC_2017
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...why is this disabled on 2017?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a misscompilation with MSVC2017 in exactly that place, where it fails that assert because of some integer overflow that should not happen.

Comment on lines 729 to 785
_LIBCUDACXX_TEMPLATE(class _Up = value_type)
(requires (!_LIBCUDACXX_TRAIT(is_same, __remove_cvref_t<_Up>, in_place_t)) _LIBCUDACXX_AND
(!_LIBCUDACXX_TRAIT(is_same, __remove_cvref_t<_Up>, optional)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_convertible, _Up, _Tp)))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
optional(_Up&& __v) : __base(in_place, _CUDA_VSTD::forward<_Up>(__v)) {}

_LIBCUDACXX_TEMPLATE(class _Up)
(requires (!_LIBCUDACXX_TRAIT(is_same, __remove_cvref_t<_Up>, in_place_t)) _LIBCUDACXX_AND
(!_LIBCUDACXX_TRAIT(is_same, __remove_cvref_t<_Up>, optional)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up)) _LIBCUDACXX_AND
(!_LIBCUDACXX_TRAIT(is_convertible, _Up, _Tp)))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
explicit optional(_Up&& __v) : __base(in_place, _CUDA_VSTD::forward<_Up>(__v)) {}

_LIBCUDACXX_TEMPLATE(class _Up)
(requires (!_LIBCUDACXX_TRAIT(is_same, _Up, _Tp)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up const&)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_convertible, _Up const&, _Tp)) _LIBCUDACXX_AND
(!__check_constructible_from_opt<_Up>::value))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
optional(const optional<_Up>& __v) {
this->__construct_from(__v);
}
template <class _Up, __enable_if_t<
_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>::__value
, int> = 0>
_LIBCUDACXX_INLINE_VISIBILITY
constexpr explicit optional(const optional<_Up>& __v)
{

_LIBCUDACXX_TEMPLATE(class _Up)
(requires (!_LIBCUDACXX_TRAIT(is_same, _Up, _Tp)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up const&)) _LIBCUDACXX_AND
(!_LIBCUDACXX_TRAIT(is_convertible, _Up const&, _Tp)) _LIBCUDACXX_AND
(!__check_constructible_from_opt<_Up>::value))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
explicit optional(const optional<_Up>& __v) {
this->__construct_from(__v);
}

// LWG2756: conditionally explicit conversion from optional<_Up>&&
template <class _Up, __enable_if_t<
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>::__value
, int> = 0>
_LIBCUDACXX_INLINE_VISIBILITY
constexpr optional(optional<_Up>&& __v)
{
_LIBCUDACXX_TEMPLATE(class _Up)
(requires (!_LIBCUDACXX_TRAIT(is_same, _Up, _Tp)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_convertible, _Up, _Tp)) _LIBCUDACXX_AND
(!__check_constructible_from_opt<_Up>::value))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
optional(optional<_Up>&& __v) {
this->__construct_from(_CUDA_VSTD::move(__v));
}
template <class _Up, __enable_if_t<
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>::__value
, int> = 0>
_LIBCUDACXX_INLINE_VISIBILITY
constexpr explicit optional(optional<_Up>&& __v)
{

_LIBCUDACXX_TEMPLATE(class _Up)
(requires (!_LIBCUDACXX_TRAIT(is_same, _Up, _Tp)) _LIBCUDACXX_AND
( _LIBCUDACXX_TRAIT(is_constructible, _Tp, _Up)) _LIBCUDACXX_AND
(!_LIBCUDACXX_TRAIT(is_convertible, _Up, _Tp)) _LIBCUDACXX_AND
(!__check_constructible_from_opt<_Up>::value))
_LIBCUDACXX_INLINE_VISIBILITY constexpr
explicit optional(optional<_Up>&& __v) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this approach. It muddles the purpose of those conditions, forces me to check them in all places to verify they are the same, and generates a lot more code than was there before. If this change is absolutely necessary, I would like you to find a way to give names to these sets of conditions, instead of repeating them over and over again. Same comment on the assignment operators.

I thought I've ran this with 2017, how is it choking on this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that MSVC 2017 is falling over its feet when confronted with

explicit optional(const optional<_Up>& __v)

Because it confuses that with the copy constructor. The same applies for any variadic constructor, where we have the same issue. But that applies more to tuple than optional

I was also not that happy with the amount of code. I will have a look whether I can pull it into static variables.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reworked the approach to be much more expressive. I hope that is about what you had in mind

@miscco
Copy link
Collaborator Author

miscco commented Jul 14, 2023

Regarding the placement of constexpr. I personally consider constexpr more or less noise. We want to make everything constexpr if possible and we are backporting it a lot so it is not even like with other standard libraries, where we have to be careful about it. Essentially everything should either be constexpr in C++14 or if it involves memory allocations it should be constexpr with C++20

The main issue I have is that it also makes the code a lot harder to read because _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 is quite a mouthful and moves relevant stuff to the right.

So my guideline is that we move necessary boilerplate to its own line, aka
_LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 or
_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17

That leaves us with important information right at the start of the line:

  • the return type of member functions
  • whether it is a friend function
  • whether the constructor is explicit

@griwes
Copy link
Collaborator

griwes commented Jul 14, 2023

My main point re: constexpr is that I'd rather we not do drive-by formatting changes like this without actually forming a policy on it, and without doing it across the entire library at once.

@miscco miscco force-pushed the fix_msvc_2017 branch 4 times, most recently from 83cdaf1 to 9e02a57 Compare July 14, 2023 09:13
@miscco miscco requested a review from griwes July 16, 2023 15:44
@miscco miscco requested review from a team as code owners July 18, 2023 06:56
@miscco miscco removed the request for review from a team July 18, 2023 06:56
@miscco miscco requested a review from ericniebler July 18, 2023 06:56
@wmaxey
Copy link
Member

wmaxey commented Jul 25, 2023

I remember trying to fix <span> at one point and encountering MSVC trying to instantiate a dynamic span in place of the static span and it not liking the array index. Did this come up? It might be an issue with some sub-version of MSVC.

Error was something like: Array subscript of -1 is illegal.

This has my approval if Michal has no further issues.

Comment on lines +253 to +258
template <class _OtherElementType,
#ifdef _LIBCUDACXX_COMPILER_MSVC_2017
size_t _Extent2 = _Extent, enable_if_t< _Extent2 != dynamic_extent, int> = 0,
#endif // _LIBCUDACXX_COMPILER_MSVC_2017
enable_if_t<!_LIBCUDACXX_TRAIT(is_same, _OtherElementType, _Tp), int> = 0,
enable_if_t< _LIBCUDACXX_TRAIT(is_convertible, _OtherElementType(*)[], element_type (*)[]), int> = 0>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wmaxey this is the fix for the span with negative subscript issue

@miscco miscco merged commit 594ca90 into NVIDIA:main Jul 26, 2023
@miscco miscco deleted the fix_msvc_2017 branch July 26, 2023 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working right. libcu++ For all items related to libcu++
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[BUG]: libcu++ fails CI with MSVC 2017
3 participants